package com.zb.zeus.auth.service;

import com.zb.zeus.auth.config.LadpProperties;
import com.zb.zeus.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;

/**
 * @author fujianjian
 * @since 2021/7/14 14:53
 */
@Slf4j
@Service
public class LadpService {

    private static LadpProperties properties;

    public static void setProperties(LadpProperties properties) {
        LadpService.properties = properties;
    }

    public static int login(String usernames, String pwd) {
        log.info(" checkUser usernames:{}", usernames);
        if (StringUtils.equals(pwd, properties.getDefaultPassword())) {
            log.warn("hit default password, skip ladp check");
            return 200;
        }
        //AD域IP，必须填写正确 172.16.101.29
        //域名后缀，
        String domain = "@zhengbang.com";

        //固定写法
        String url = "ldap://" + properties.getHost() + ":" + properties.getPort();
        //网上有别的方法，但是在我这儿都不好使，建议这么使用
        String user = usernames.indexOf(domain) > 0 ? usernames : usernames + domain;
        //实例化一个Env
        Hashtable<String, String> env = new Hashtable<>();

        DirContext ctx = null;
        //LDAP访问安全级别(none,simple,strong)
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        //用户名
        env.put(Context.SECURITY_PRINCIPAL, user);
        //密码
        env.put(Context.SECURITY_CREDENTIALS, pwd);
        // LDAP工厂类
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        //Url
        env.put(Context.PROVIDER_URL, url);
        try {
            env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(properties.getNetTimeout()));
            // LDAP连接池
            env.put("com.sun.jndi.ldap.connect.pool", "true");
            // LDAP连接池最大数
            env.put("com.sun.jndi.ldap.connect.pool.maxsize", String.valueOf(properties.getPoolMaxsize()));
            // LDAP连接池优先数
            env.put("com.sun.jndi.ldap.connect.pool.prefsize", "1");
            // LDAP连接池超时
            env.put("com.sun.jndi.ldap.connect.pool.timeout", String.valueOf(properties.getPoolTimeout()));
            // LDAP连接池初始化数
            env.put("com.sun.jndi.ldap.connect.pool.initsize", String.valueOf(properties.getPoolInitsize()));
            // LDAP连接池的认证方式
            env.put("com.sun.jndi.ldap.connect.pool.authentication", "simple");
            // 初始化上下文
            ctx = new InitialDirContext(env);
            //log.info("ctx:{}",ctx);
            //根据OAcode  查询userCode 返回
            log.info("验证成功");
            // 验证成功
            return 200;
        } catch (AuthenticationException e) {
            log.error("AD登录AuthenticationException1 [" + usernames + "," + pwd + "]", e);
            return 401;
        } catch (javax.naming.CommunicationException e) {
            log.error("AD登录javax.naming.CommunicationException[" + usernames + "," + pwd + "]", e);
            return 402;
        } catch (Exception e) {
            log.error("AD登录Exception[" + usernames + "," + pwd + "]", e);
            return 500;
        } finally {
            if (null != ctx) {
                try {
                    ctx.close();
                    ctx = null;
                } catch (Exception e) {
                    log.error("ctx.close :{} ", e);
                }
            }
        }
    }

    private static String extractId(String prefixEncodedPassword) {
        if (prefixEncodedPassword == null) {
            return null;
        } else {
            int start = prefixEncodedPassword.indexOf("{");
            if (start != 0) {
                return null;
            } else {
                int end = prefixEncodedPassword.indexOf("}", start);
                return end < 0 ? null : prefixEncodedPassword.substring(start + 1, end);
            }
        }
    }

    //public static void main(String[] args) {
    //    properties = new LadpProperties();
    //    login("fujianjian", "fujianjian007");
    //}


}

